﻿using Blog1._0.Data;
using Blog1._0.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Text;
using Until;

namespace Blog1._0.Service
{
    /// <summary>
    /// 【博客】逻辑层
    /// </summary>
    public class ArticleService : Repository
    {
        /// <summary>
        /// 获取置顶文章（默认前三）
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public IEnumerable<MenuInfo> GetDingArticle(int num)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>();
            var query = (from u in article
                         where u.IsTop == true &&
                         u.IsActive == true
                         orderby u.ViewTimes descending
                         orderby u.CRT_Time descending
                         select new MenuInfo()
                         {
                             id = u.ArticleID,
                             name = u.ArticleTitle
                         }).Take(num);

            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].file = Des.DesEncrypt("guo", Lists[i].id.ToString());
            }
            return Lists.ToList();
        }

        /// <summary>
        /// 获取热门文章
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public IEnumerable<ArticleModel> GetHotArticle(int num)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>();
            var type = db.IQueryable<Guo_Type>();
            var catalog = db.IQueryable<Guo_Catalog>();
            var query = (from u in article
                         join k in type
                         on u.TypeID equals k.TypeID
                         join o in catalog
                         on u.CatalogID equals o.CatalogID
                         where u.IsActive == true
                         orderby u.ViewTimes descending
                         orderby u.CRT_Time descending
                         select new ArticleModel()
                         {
                             ArticleID = u.ArticleID,
                             Test = "",
                             ArticleTitle = u.ArticleTitle,
                             TypeID = u.TypeID,
                             TypeName = k.TypeName,
                             CatalogID = u.CatalogID,
                             CatalogName = o.CatalogName,
                             ImgUrl = u.ImgUrl,
                             Abstract = u.Abstract,
                             CRT_Time = u.CRT_Time
                         }).Take(num);

            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }
            return Lists.ToList();
        }

        /// <summary>
        /// 访客
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public IEnumerable<QQUser> GetByQQUserList(int num)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_QQUser>();
            var query = (from u in article
                         orderby u.LastLogin descending
                         select new QQUser()
                         {
                             Id = u.Id,
                             NickName = u.NickName,
                             Gender = u.Gender,
                             HeadShot = u.HeadShot,
                             Status = u.Status
                         }).Take(num);

            return query.ToList();
        }

        /// <summary>
        /// 文章总条数
        /// </summary>
        /// <returns></returns>
        public int GetByQQUserNum()
        {
            return this.Base().IQueryable<Guo_Acticle>(t => t.IsActive == true).Count();
        }

        /// <summary>
        /// 增加浏览次数
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public int GetViewAdd(int Id)
        {
            var db = this.Base();
            var article = db.FindEntity<Guo_Acticle>(t => t.ArticleID == Id);
            if (article.ViewTimes == null)
            {
                article.ViewTimes = 0;
                article.ViewTimes += 1;
            }
            else
            {
                article.ViewTimes += 1;
            }
            db.Update(article);//更新

            return db.Commit();
        }

        /// <summary>
        /// 获取文章详情 数据
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public IEnumerable<ArticleModel> GetArticleInfo(int Id)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>(t => t.ArticleID == Id);
            var type = db.IQueryable<Guo_Type>();
            var catalog = db.IQueryable<Guo_Catalog>();
            var user = db.IQueryable<Guo_User>();
            var query = from u in article
                        join k in type
                        on u.TypeID equals k.TypeID
                        join o in catalog
                        on u.CatalogID equals o.CatalogID
                        join q in user on
                        u.UserID equals q.ID
                        select new ArticleModel()
                        {
                            ArticleID = u.ArticleID,
                            ArticleTitle = u.ArticleTitle,
                            TypeID = u.TypeID,
                            TypeName = k.TypeName,
                            Content = u.Content,
                            CatalogID = u.CatalogID,
                            CatalogName = o.CatalogName,
                            UserName = q.UserName,
                            ImgUrl = u.ImgUrl,
                            Abstract = u.Abstract,
                            CRT_Time = u.CRT_Time,
                            ViewTimes = u.ViewTimes,
                            Wyyun = u.Wyyun
                        };

            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }

            return Lists;
        }

        /// <summary>
        /// 延伸阅读-获取两条随机文章
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public IEnumerable<ArticleModel> GetRandomArticleList(int num)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>();
            var query = (from u in article
                         select new ArticleModel()
                         {
                             ArticleID = u.ArticleID,
                             ArticleTitle = u.ArticleTitle
                         }).OrderBy(x => Guid.NewGuid()).Take(num);

            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }

            return Lists.ToList();
        }

        public int GetComment(int Id)
        {
            return this.Base().IQueryable<Guo_Comment>(t => t.ParentId == 0 && t.Id == Id).Count();
        }

        /// <summary>
        /// 博客页面-线性查询文章列表
        /// </summary>
        /// <param name="classId"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public string GetListByClassId(int classId, int page, int pagesize)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>();
            var type = db.IQueryable<Guo_Type>();
            var catalog = db.IQueryable<Guo_Catalog>();
            var comment = db.IQueryable<Guo_Comment>();

            #region Linq 分页
            if (classId != 0)
            {
                var query = (from a in article
                             join b in type on new { TypeID = (int)a.TypeID } equals new { TypeID = b.TypeID }
                             join c in catalog on new { CatalogID = (int)a.CatalogID } equals new { CatalogID = c.CatalogID }
                             join d in comment on new { ArticleID = a.ArticleID } equals new { ArticleID = (int)d.ArticleId } into d_join
                             from d in d_join.DefaultIfEmpty()
                             where
                               a.IsActive == true && a.CatalogID == classId
                             group new { a, c, b, d } by new
                             {
                                 a.ArticleID,
                                 a.ArticleTitle,
                                 a.Abstract,
                                 a.ImgUrl,
                                 c.CatalogName,
                                 b.TypeName,
                                 a.IsTop,
                                 a.ViewTimes,
                                 a.IsActive,
                                 a.CRT_Time
                             } into g
                             orderby
                               g.Key.IsTop descending,
                               g.Key.CRT_Time descending
                             select new ArticleModel()
                             {
                                 ArticleID = (int)g.Key.ArticleID,
                                 ArticleTitle = g.Key.ArticleTitle,
                                 Abstract = g.Key.Abstract,
                                 ImgUrl = g.Key.ImgUrl,
                                 CatalogName = g.Key.CatalogName,
                                 TypeName = g.Key.TypeName,
                                 IsTop = (bool?)g.Key.IsTop,
                                 ViewTimes = (int?)g.Key.ViewTimes,
                                 Replies = (int?)g.Count(),
                                 IsActive = (bool?)g.Key.IsActive,
                                 CRT_Time = (DateTime)g.Key.CRT_Time
                             }).Skip((page - 1) * pagesize).Take(pagesize);

                //页码Page初始值定义为0时则： Skip(page * pagesize).Take(pagesize).ToList();

                string articleHtml = CreateArticleHtml(query);
                return articleHtml;
            }
            else
            {
                var query = (from a in article
                             join b in type on new { TypeID = (int)a.TypeID } equals new { TypeID = b.TypeID }
                             join c in catalog on new { CatalogID = (int)a.CatalogID } equals new { CatalogID = c.CatalogID }
                             join d in comment on new { ArticleID = a.ArticleID } equals new { ArticleID = (int)d.ArticleId } into d_join
                             from d in d_join.DefaultIfEmpty()
                             where
                               a.IsActive == true
                             group new { a, c, b, d } by new
                             {
                                 a.ArticleID,
                                 a.ArticleTitle,
                                 a.Abstract,
                                 a.ImgUrl,
                                 c.CatalogName,
                                 b.TypeName,
                                 a.IsTop,
                                 a.ViewTimes,
                                 a.IsActive,
                                 a.CRT_Time
                             } into g
                             orderby
                               g.Key.IsTop descending,
                               g.Key.CRT_Time descending
                             select new ArticleModel()
                             {
                                 ArticleID = (int)g.Key.ArticleID,
                                 ArticleTitle = g.Key.ArticleTitle,
                                 Abstract = g.Key.Abstract,
                                 ImgUrl = g.Key.ImgUrl,
                                 CatalogName = g.Key.CatalogName,
                                 TypeName = g.Key.TypeName,
                                 IsTop = (bool?)g.Key.IsTop,
                                 ViewTimes = (int?)g.Key.ViewTimes,
                                 Replies = (int?)g.Count(),
                                 IsActive = (bool?)g.Key.IsActive,
                                 CRT_Time = (DateTime)g.Key.CRT_Time
                             }).Skip((page - 1) * pagesize).Take(pagesize);

                string articleHtml = CreateArticleHtml(query);
                return articleHtml;
            }
            #endregion

        }

        /// <summary>
        /// 拼接文章字符串
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private string CreateArticleHtml(IEnumerable<ArticleModel> list)
        {
            var Lists = list.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }
            StringBuilder sb = new StringBuilder();
            if (Lists != null)
            {
                foreach (ArticleModel item in Lists)
                {
                    string links = "/Article/Detail?DPOR369E0zc=" + item.Test;
                    #region 拼接字符串
                    sb.AppendFormat(@"<section class='article-item zoomIn article'>
                                        {0}
                                        <h5 class='title'>
                                            <span class='fc-blue'>【{1}】</span>
                                            <a href='{11}'>{2}</a>
                                        </h5>
                                        <div class='time'>
                                            <span class='day'>{3}</span>
                                            <span class='month fs-18'>{4}<span class='fs-14'>月</span></span>
                                            <span class='year fs-18 ml10'>{5}</span>
                                        </div>
                                        <div class='content'>
                                            <a href='{12}' class='cover img-light'>
                                                <img src='{6}' >
                                            </a>
                                            {7}
                                        </div>
                                        <div class='read-more'>
                                            <a href='{13}' class='fc-black f-fwb'>继续阅读</a>
                                        </div>
                                        <aside class='f-oh footer'>
                                            <div class='f-fl tags'>
                                                <span class='fa fa-tags fs-16'></span>
                                                <a class='tag'>{8}</a>
                                            </div>
                                            <div class='f-fr'>
                                                <span class='read'>
                                                    <i class='fa fa-eye fs-16'></i>
                                                    <i class='num'>{9}</i>
                                                </span>
                                                <span class='ml20'>
                                                    <i class='fa fa-comments fs-16'></i>
                                                    <a href = 'javascript:void(0)' class='num fc-grey'>{10}</a>
                                                </span>
                                            </div>
                                        </aside><div class='line'></div>
                                    </section>", item.IsTop == true ? "<div class='fc-flag'>置顶</div>" : "",
                                    item.TypeName, item.ArticleTitle, item.CRT_Time.ToString("dd"), item.CRT_Time.ToString("MM"),
                                    item.CRT_Time.ToString("yyyy"), item.ImgUrl, item.Abstract, item.CatalogName, item.ViewTimes,
                                    item.Replies, links, links, links);
                    #endregion
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 获得文章所有年份（文章归档使用）
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ArticleModel> Getyear()
        {
            var db = this.Base();
            var diay = db.IQueryable<Guo_Acticle>();
            var query = from guo_qquser in diay
                        group guo_qquser by new
                        {
                            Column1 =2020
                        } into g
                        orderby
                          g.Key.Column1 descending
                        select new ArticleModel()
                        {
                            Years = g.Key.Column1
                        };
            return query.ToList();
        }

        /// <summary>
        /// 【文章归档】
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ArticleModel> GetAll()
        {
            var db = this.Base();
            var diay = db.IQueryable<Guo_Acticle>();
            var query = from u in diay
                        orderby u.CRT_Time descending
                        select new ArticleModel()
                        {
                            ArticleID = u.ArticleID,
                            ArticleTitle = u.ArticleTitle,
                            CRT_Time = u.CRT_Time
                        };
            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }

            return Lists.ToList();
        }

        /// <summary>
        /// 文章搜索
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IEnumerable<ArticleModel> GetArticleListBySearch(string content)
        {
            var db = this.Base();
            var article = db.IQueryable<Guo_Acticle>().Where(t => t.ArticleTitle.Contains(content));
            var query = from i in article
                        orderby i.ViewTimes, i.CRT_Time descending
                        select new ArticleModel()
                        {
                            ArticleID = (int)i.ArticleID,
                            ArticleTitle = i.ArticleTitle,
                            Abstract = i.Abstract,
                            IsActive = (bool?)i.IsActive,
                            CRT_Time = (DateTime)i.CRT_Time
                        };

            var Lists = query.ToList();
            for (int i = 0; i < Lists.Count(); i++)
            {
                Lists[i].Test = Des.DesEncrypt("guo", Lists[i].ArticleID.ToString());
            }

            return Lists.ToList();
        }

        /// <summary>
        /// 加载评论列表
        /// </summary>
        /// <param name="articleId"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public string GetFlowArticleComment(int articleId, int page, int pagesize)
        {
            var db = this.Base();
            var comment = db.IQueryable<Guo_Comment>();
            var user = db.IQueryable<Guo_QQUser>();

            var query = (from a in comment
                         join b in user on new { SendId = (int)a.SendId } equals new { SendId = b.Id } into b_join
                         from b in b_join.DefaultIfEmpty()
                         join c in user on new { AcceptId = (int)a.AcceptId } equals new { AcceptId = c.Id } into c_join
                         from c in c_join.DefaultIfEmpty()
                         where
                           a.ParentId == 0 &&
                           a.ArticleId == articleId
                         orderby
                           a.CreateOn descending
                         select new CommentModel()
                         {
                             Id = a.Id,
                             SendId = a.SendId,
                             AcceptId = a.AcceptId,
                             Content = a.Content,
                             Status = a.Status,
                             ParentId = a.ParentId,
                             ArticleId = a.ArticleId,
                             CreateOn = a.CreateOn,
                             SendNickName = b.NickName,
                             AcceptNickName = c.NickName,
                             HeadShot = b.HeadShot
                         }).Skip((page - 1) * pagesize).Take(pagesize);

            //子级评论
            var query1 = from a in comment
                         join b in user on new { SendId = (int)a.SendId } equals new { SendId = b.Id } into b_join
                         from b in b_join.DefaultIfEmpty()
                         join c in user on new { AcceptId = (int)a.AcceptId } equals new { AcceptId = c.Id } into c_join
                         from c in c_join.DefaultIfEmpty()
                         where
                           a.ParentId != 0 &&
                           a.ArticleId == articleId
                         orderby
                           a.CreateOn descending
                         select new CommentModel()
                         {
                             Id = a.Id,
                             SendId = a.SendId,
                             AcceptId = a.AcceptId,
                             Content = a.Content,
                             Status = a.Status,
                             ParentId = a.ParentId,
                             ArticleId = a.ArticleId,
                             CreateOn = a.CreateOn,
                             SendNickName = b.NickName,
                             AcceptNickName = c.NickName,
                             HeadShot = b.HeadShot
                         };

            //返回字符串
            string articleCommentHtml = CreateArticleCommentHtml(query.ToList(), query1.ToList());
            return articleCommentHtml;
        }

        /// <summary>
        /// 拼接评论字符串
        /// </summary>
        /// <param name="parentList"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private string CreateArticleCommentHtml(IEnumerable<CommentModel> parentList, IEnumerable<CommentModel> list)
        {
            string OpenComment = Configs.GetValue("OpenComment");
            string replyBtn = "<a href='javascript:;' class='btn-reply' data-targetid='{0}' data-targetname='{1}'>回复</a>";
            StringBuilder sb = new StringBuilder();
            if (parentList != null && list != null)
            {
                foreach (CommentModel item in parentList)
                {
                    sb.AppendFormat(@"<li>
                                <div class='comment-parent'>
                                    <a name='remark-{0}'></a><img src='{1}'>
                                    <div class='info'>
                                        <span class='username'>{2}</span>
                                    </div>
                                    <div class='comment-content'>{3}</div>
                                    <p class='info info-footer'>
                                        <span class='comment-time'>{4}</span>{5}
                                    </p>

                                </div>
                                <hr>", item.Id, item.HeadShot, item.SendNickName, item.Content, item.CreateOn, OpenComment == "true" ? string.Format(replyBtn, item.SendId, item.SendNickName) : "回复已关闭");
                    foreach (CommentModel model in list)
                    {
                        if (item.Id == model.ParentId)
                        {
                            sb.AppendFormat(@"<div class='comment-child'>
                                            <a name='reply-{0}'></a><img src='{1}'>
                                            <div class='info'>
                                                <span class='username'>{2}</span><span style='padding-right:0;margin-left:-5px;'> 回复 </span><span class='username'>{3}</span><span>{4}</span>
                                            </div>
                                            <p class='info'>
                                                <span class='comment-time'>{5}</span>{6}
                                            </p>
                                        </div>", model.Id, model.HeadShot, model.SendNickName, model.AcceptNickName, model.Content, model.CreateOn, OpenComment == "true" ? string.Format(replyBtn, model.SendId, model.SendNickName) : "回复已关闭");
                        }
                    }
                    sb.AppendFormat(@"<div class='replycontainer layui-hide'>
                                    <form class='layui-form' action=''>
                                        <input type='hidden' name='remarkId' value='{0}'><input type='hidden' name='targetUserId' value='0'><input type='hidden' name='articleId' value='{1}'>
                                        <div class='layui-form-item'>
                                            <textarea name='replyContent' lay-verify='replyContent' placeholder='请输入回复内容' class='layui-textarea' style='min-height:80px;'></textarea>
                                        </div>
                                        <div class='layui-form-item'>
                                            <button class='layui-btn layui-btn-xs' lay-submit='formReply' lay-filter='formReply'>提交</button>
                                        </div>
                                    </form>
                                </div>
                            </li>", item.Id, item.ArticleId);
                }
            }
            return sb.ToString();
        }
    }
}
